﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Streambolics;

namespace MacNs
{
    public class NameDatabaseEventArgs
    {
        private string _Name;
        private string _OldIp;
        private string _NewIp;

        public NameDatabaseEventArgs (string aName, string aOldIp, string aNewIp)
        {
            _Name = aName;
            _OldIp = aOldIp;
            _NewIp = aNewIp;
        }

        public string Name
        {
            get
            {
                return _Name;
            }
        }

        public string OldIp
        {
            get
            {
                return _OldIp;
            }
        }

        public string NewIp
        {
            get
            {
                return _NewIp;
            }
        }
    }

    public delegate void NameDatabaseEventHandler (object sender, NameDatabaseEventArgs e);

    /// <summary>
    ///     A database of Names-to-IP mappings.
    /// </summary>
    public class NameDatabase
    {
        private Dictionary<string, string> _Mapping = new Dictionary<string, string> ();

        public event NameDatabaseEventHandler Changed;

        /// <summary>
        ///     Adds or replace the mapping between an IP address
        ///     and a name.
        /// </summary>
        /// <param name="IpAddress">
        ///     The IP address
        /// </param>
        /// <param name="Name">
        ///     The name.
        /// </param>
        
        public void AddMapping (string IpAddress, string Name)
        {
            string r = "";
            if (_Mapping.TryGetValue (Name, out r) && Name == r)
            {
                return;
            }

            _Mapping[Name] = IpAddress;
            OnChanged (new NameDatabaseEventArgs(Name, r, IpAddress));
        }

        protected void OnChanged (NameDatabaseEventArgs e)
        {
            GlobalLog.Log ("Mapping added {0} = {1}", e.Name, e.NewIp);
            if (Changed != null)
            {
                Changed (this, e);
            }
        }

        /// <summary>
        ///     Resolves a name to an IP address 
        /// </summary>
        /// <param name="Name">
        ///     The name to resolve
        /// </param>
        /// <returns>
        ///     An IP address in textual form, or null if not
        ///     found.
        /// </returns>

        public string Resolve (string Name)
        {
            string r;

            if (_Mapping.TryGetValue (Name, out r))
            {
                return r;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        ///     A string representing the contents of a LMHOSTS file.
        /// </summary>
        /// <returns>
        ///     The string to be saved to the LMHOSTS file.
        /// </returns>

        public string AsHostsFile ()
        {
            StringBuilder b = new StringBuilder();

            foreach (var v in _Mapping)
            {
                b.Append (v.Value);
                b.Append ('\t');
                b.AppendLine (v.Key);
            }
            return b.ToString ();
        }
    }
}
